package com.lenovo.lcdm.dcm.service.impl;

import com.amazonaws.HttpMethod;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.lenovo.lcdm.common.enums.CommonMsgEnum;
import com.lenovo.lcdm.common.enums.DeleteFlagEnum;
import com.lenovo.lcdm.dcm.common.RemoteObjectStorageSupport;
import com.lenovo.lcdm.common.exception.BusinessException;
import com.lenovo.lcdm.dcm.common.util.ContextUtil;
import com.lenovo.lcdm.dcm.dto.AttachmentDto;
import com.lenovo.lcdm.dcm.entity.DcmAttachmentLink;
import com.lenovo.lcdm.dcm.service.DcmAttachmentLinkService;
import com.lenovo.lcdm.dcm.mapper.DcmAttachmentLinkMapper;
import com.lenovo.lcdm.dcm.common.util.ObjectUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.util.*;
import java.util.stream.Collectors;

/**
* @author xujing30
* @description 针对表【dcm_attachment_link】的数据库操作Service实现
* @createDate 2024-01-22 17:24:13
*/
@Slf4j
@Service
public class DcmAttachmentLinkServiceImpl extends ServiceImpl<DcmAttachmentLinkMapper, DcmAttachmentLink>
    implements DcmAttachmentLinkService{

    @Autowired
    private RemoteObjectStorageSupport remoteObjectStorageSupport;

    @Override
    public List<DcmAttachmentLink> getByObjectId(List<Long> ids) {
        List<DcmAttachmentLink> attachmentLinks = new ArrayList<>();
        LambdaQueryWrapper<DcmAttachmentLink> attachmentLinkQw = new LambdaQueryWrapper<>();
        attachmentLinkQw.in(DcmAttachmentLink::getObjectId, ids).eq(DcmAttachmentLink::getDeleted, DeleteFlagEnum.NO.getValue());
        attachmentLinks = list(attachmentLinkQw);
        return attachmentLinks;
    }

    @Override
    public DcmAttachmentLink getByObjectIdAndName(String objectName, Long id) {
        LambdaQueryWrapper<DcmAttachmentLink> attachmentLinkQw = new LambdaQueryWrapper<>();
        attachmentLinkQw.eq(DcmAttachmentLink::getObjectId, id).eq(DcmAttachmentLink::getObjectName, objectName).eq(DcmAttachmentLink::getDeleted, DeleteFlagEnum.NO.getValue());
        return getOne(attachmentLinkQw);
    }

    @Override
    public DcmAttachmentLink getByAttachmentIdAndObjectName(Long attachmentId, String objectName) {
        LambdaQueryWrapper<DcmAttachmentLink> attachmentLinkQw = new LambdaQueryWrapper<>();
        attachmentLinkQw.eq(DcmAttachmentLink::getAttachmentId, attachmentId).eq(DcmAttachmentLink::getObjectName, objectName).eq(DcmAttachmentLink::getDeleted, DeleteFlagEnum.NO.getValue());
        return getOne(attachmentLinkQw);
    }

    @Override
    public String getFileNameByAttachmentId(String attachmentId) {
        String fileName = "";
        LambdaQueryWrapper<DcmAttachmentLink> attachmentLinkQw = new LambdaQueryWrapper<>();
        attachmentLinkQw.eq(DcmAttachmentLink::getAttachmentId, attachmentId).eq(DcmAttachmentLink::getDeleted, DeleteFlagEnum.NO.getValue());
        DcmAttachmentLink attachmentLink = getOne(attachmentLinkQw, false);
        if(attachmentLink == null){
            throw new BusinessException("File does not exist.", CommonMsgEnum.FAIL.getCode());
        }
        if(StringUtils.isEmpty(attachmentLink.getFileName())){
            fileName = attachmentLink.getObjectName() + "." + attachmentLink.getAttachmentType();
        }else {
            fileName = attachmentLink.getFileName();
        }
        return fileName;
    }

    @Override
    public Map<String, String> getFileNamesByAttachmentId(String[] attachmentId) {
        LambdaQueryWrapper<DcmAttachmentLink> attachmentLinkQw = new LambdaQueryWrapper<>();
        attachmentLinkQw.in(DcmAttachmentLink::getAttachmentId, attachmentId).eq(DcmAttachmentLink::getDeleted, DeleteFlagEnum.NO.getValue());
        List<DcmAttachmentLink> attachmentLink = list(attachmentLinkQw);
        if(attachmentLink == null){
            throw new BusinessException("File does not exist.", CommonMsgEnum.FAIL.getCode());
        }
        return attachmentLink.stream().collect(Collectors.toMap(DcmAttachmentLink::getAttachmentId, DcmAttachmentLink::getFileName));
    }

    @Override
    public String uploadAttachment(AttachmentDto attachmentDto) {
        MultipartFile file = attachmentDto.getFile();
        String objectName = attachmentDto.getObjectName();
        Set<Long> objectIds = attachmentDto.getObjectId();
        if(ObjectUtil.isAnyEmpty(file, objectName, objectIds)){
            throw new BusinessException("Parameter cannot be empty.", CommonMsgEnum.FAIL.getCode());
        }
        String key = UUID.randomUUID().toString();
        try {
            remoteObjectStorageSupport.putObject(key, file.getInputStream(), file.getSize());
        }catch (Exception e){
            throw new BusinessException("Upload file error:" + e.getMessage(), CommonMsgEnum.FAIL.getCode());
        }
        objectIds.forEach(objectId -> {
            this.saveLink(key, file.getOriginalFilename(), file.getSize(), objectName, objectId);
        });
        return key;
    }

    @Override
    public void saveLink(String attachmentId, String fileName, Long fileSize, String objectName, Long objectId){
        Date now = new Date();
        String type = fileName.substring(fileName.indexOf(".") + 1);
        DcmAttachmentLink link = new DcmAttachmentLink();
        link.setAttachmentId(attachmentId);
        link.setFileName(fileName);
        link.setAttachmentType(type);
        link.setFileSize(fileSize);
        link.setObjectId(objectId);
        link.setObjectName(objectName);
        link.setCreator(ContextUtil.getCurrentUser());
        link.setCreateTime(now);
        link.setModifier(ContextUtil.getCurrentUser());
        link.setModifyTime(now);
        this.save(link);
        log.info("Save attachment link successful.");
    }

    @Override
    public String getUrlByObjectIdAndName(Long id, String objectName) {
        LambdaQueryWrapper<DcmAttachmentLink> attachmentLinkQw = new LambdaQueryWrapper<>();
        attachmentLinkQw.eq(DcmAttachmentLink::getObjectId, id).eq(DcmAttachmentLink::getObjectName, objectName).eq(DcmAttachmentLink::getDeleted, DeleteFlagEnum.NO.getValue());
        DcmAttachmentLink one = getOne(attachmentLinkQw);
        if (one != null) {
            return remoteObjectStorageSupport.getPreSignedUrl(one.getAttachmentId(), one.getFileName(), HttpMethod.GET);
        }
        return null;
    }

    @Override
    public String downloadAttachment(String attachmentId) {
        String fileName = getFileNameByAttachmentId(attachmentId);
        return remoteObjectStorageSupport.getPreSignedUrl(attachmentId, fileName, HttpMethod.GET);
    }
}




